// MainFrm.cpp : implmentation of the CMainFrame class
//
/////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "resource.h"

#include "QuicksView.h"
#include "MainFrm.h"
#include "AlphaBlend.h"
#include "hr_time.h"

CMainFrame::CMainFrame(HINSTANCE hInstance) : m_init(false), m_view(this), m_hInstance(hInstance) {}

BOOL CMainFrame::PreTranslateMessage(MSG* pMsg)
{
	if(CFrameWindowImpl<CMainFrame>::PreTranslateMessage(pMsg))
		return TRUE;

	return m_view.PreTranslateMessage(pMsg);
}

BOOL CMainFrame::OnIdle()
{
	if (!m_init) {
		ShowWindow(SW_SHOW);
		m_init = true;
	}
	return FALSE;
}

HWND hStaticQuicksView;
CStopWatch keyDelay;
int downCalls = 0;
int upCalls = 0;
BOOL bGotDown = FALSE;

LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
  BOOL fEatKeystroke = FALSE;
  if (nCode == HC_ACTION) 
  {
     switch (wParam) 
	 {
		case WM_KEYDOWN:  
		case WM_SYSKEYDOWN:
			{
				PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT) lParam;
				if (!bGotDown && p->vkCode == VK_LWIN) {
					keyDelay.startTimer();
					downCalls++;
					bGotDown = TRUE;
				}
			}
			break;
		case WM_KEYUP:    
		case WM_SYSKEYUP:
			{
				PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT) lParam;
				ULONG_PTR ex = p->dwExtraInfo;
				
				if (p->vkCode == VK_LWIN) {
					upCalls++;
					keyDelay.stopTimer();
					double s = keyDelay.getElapsedTime();
					if (s > 0.250) {
							fEatKeystroke = TRUE;
							::SendMessage(hStaticQuicksView, ID_SHOW, 0, 0);
					}
					bGotDown = FALSE;
				}
				break;
			}
     }
  }

  return(fEatKeystroke ? 1 : CallNextHookEx(NULL, nCode, wParam,
lParam));
}

LRESULT CMainFrame::OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{

	RECT clientrect;
	GetClientRect(&clientrect);

	RECT r;
	r.left = 0;
	r.right = clientrect.right-clientrect.left;
	r.top = 0;
	r.bottom = clientrect.bottom-clientrect.top;
	m_hWndClient = m_view.Create(m_hWnd, r, NULL, WS_CHILD|WS_VISIBLE);
	hStaticQuicksView = m_hWndClient;
	
	// Install the low-level keyboard hook for the windows key
	//m_hhkLowLevelKybd = SetWindowsHookEx(WH_KEYBOARD_LL,
	//	LowLevelKeyboardProc, m_hInstance, 0);

	// transparency
	CAlphaBlend ab(m_view);
	ab.SetTransparent();

	// register object for message filtering and idle updates
	CMessageLoop* pLoop = _Module.GetMessageLoop();
	ATLASSERT(pLoop != NULL);
	pLoop->AddMessageFilter(this);
	pLoop->AddIdleHandler(this);

	return 0;
}

LRESULT CMainFrame::OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
{
	// unregister message filtering and idle updates
	CMessageLoop* pLoop = _Module.GetMessageLoop();
	ATLASSERT(pLoop != NULL);
	pLoop->RemoveMessageFilter(this);
	pLoop->RemoveIdleHandler(this);
	
	
	UnhookWindowsHookEx(m_hhkLowLevelKybd);
	bHandled = FALSE;
	return 1;
}

LRESULT CMainFrame::OnNextMatch(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
{
	return m_view.OnNextMatch(wNotifyCode, wID, hWndCtl, bHandled);
}

LRESULT CMainFrame::OnPrevMatch(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
{
	return m_view.OnPrevMatch(wNotifyCode, wID, hWndCtl, bHandled);
}

HBRUSH CMainFrame::OnCtlColorStatic(CDCHandle dc, CStatic wndStatic) {
	dc.SetBkMode(TRANSPARENT);
	return (HBRUSH)GetStockObject(NULL_BRUSH);
}